baubs git
Commit 365b0c7ae3d16500dff3ca0ea263526b292c0a51
Parents : 08532d0
Author : Jan-Henrik Bruhn <jan-henrik.bruhn@offis.de>
Date : 2025-12-20T15:41:33+01:00
feature: Migrate AppHeader buttons and badges to shadcn/ui
- Replace Disconnect button with shadcn Button (outline variant)
- Replace status badge with shadcn Badge component
- Replace error button with shadcn Button (destructive variant)
- Use cn() helper for conditional className composition
- Preserve glass morphism effects and custom styling
Code reduction:
- Disconnect button: ~40% reduction
- Status badge: ~30% reduction
- Error button: ~60% reduction
Improved maintainability with semantic component usage and cleaner code structure.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
Changes
Diff
diff --git a/src/components/AppHeader.tsx b/src/components/AppHeader.tsx
index c5f736d..236a799 100644
--- a/src/components/AppHeader.tsx
+++ b/src/components/AppHeader.tsx
@@ -13,6 +13,9 @@ import {
ArrowPathIcon,
XMarkIcon,
} from "@heroicons/react/24/solid";
+import { Button } from "@/components/ui/button";
+import { Badge } from "@/components/ui/badge";
+import { cn } from "@/lib/utils";
export function AppHeader() {
const {
@@ -130,19 +133,24 @@ export function AppHeader() {
<div className="flex items-center gap-2 mt-1 min-h-[32px]">
{isConnected ? (
<>
- <button
+ <Button
onClick={disconnect}
- className="inline-flex items-center gap-1.5 px-2.5 py-1.5 sm:py-1 rounded text-sm font-medium bg-white/10 hover:bg-danger-600 text-primary-100 hover:text-white border border-white/20 hover:border-danger-600 cursor-pointer transition-all flex-shrink-0"
+ size="sm"
+ variant="outline"
+ className="gap-1.5 bg-white/10 hover:bg-danger-600 text-primary-100 hover:text-white border-white/20 hover:border-danger-600 flex-shrink-0"
title="Disconnect from machine"
aria-label="Disconnect from machine"
>
<XMarkIcon className="w-3 h-3" />
Disconnect
- </button>
- <span className="inline-flex items-center gap-1.5 px-2.5 py-1.5 sm:py-1 rounded text-sm font-semibold bg-white/20 text-white border border-white/30 flex-shrink-0">
+ </Button>
+ <Badge
+ variant="outline"
+ className="gap-1.5 px-2.5 py-1.5 sm:py-1 text-sm font-semibold bg-white/20 text-white border-white/30 flex-shrink-0"
+ >
<StatusIcon className="w-3 h-3" />
{machineStatusName}
- </span>
+ </Badge>
</>
) : (
<p className="text-xs text-primary-200">Not Connected</p>
@@ -150,14 +158,17 @@ export function AppHeader() {
{/* Error indicator - always render to prevent layout shift */}
<div className="relative">
- <button
+ <Button
ref={errorButtonRef}
onClick={() => setErrorPopover(!showErrorPopover)}
- className={`inline-flex items-center gap-1.5 px-2.5 py-1.5 sm:py-1 rounded text-sm font-medium bg-danger-500/90 hover:bg-danger-600 text-white border border-danger-400 transition-all flex-shrink-0 ${
+ size="sm"
+ variant="destructive"
+ className={cn(
+ "gap-1.5 flex-shrink-0",
machineErrorMessage || pyodideError
- ? "cursor-pointer animate-pulse hover:animate-none"
+ ? "animate-pulse hover:animate-none"
: "invisible pointer-events-none"
- }`}
+ )}
title="Click to view error details"
aria-label="View error details"
disabled={!(machineErrorMessage || pyodideError)}
@@ -191,7 +202,7 @@ export function AppHeader() {
return "Error";
})()}
</span>
- </button>
+ </Button>
{/* Error popover */}
{showErrorPopover && (machineErrorMessage || pyodideError) && (
Served by rngit 1.3.3 - Generated in 0.03s